package press.xiang.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import press.xiang.constant.Cache;
import press.xiang.constant.CommodityConstants;
import press.xiang.entity.Commodity;
import press.xiang.entity.Store;
import press.xiang.entity.User;
import press.xiang.entity.UserVO;
import press.xiang.service.ICommodityService;
import press.xiang.service.IStoreService;
import press.xiang.utils.TabuUtils;
import press.xiang.utils.TranUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 默认登录页面
 * @author xiang
 * @version 1.0
 * @description: TODO
 * @date 2022/4/24 9:21 上午
 */
@RestController
@AllArgsConstructor
public class LoginContoller {

    private final IStoreService storeService;
    private final ICommodityService commodityService;

    //设置默认访问页
    @RequestMapping("/")
    public String hello(){
        return "login.html";
    }


    //-----------------------------登录功能
    @RequestMapping("/login")
    public ModelAndView login(){
        return new ModelAndView("login");
    }

    @GetMapping("/loginerror") //登录错误
    public ModelAndView loginerror(){
        return new ModelAndView("login");
    }


    @GetMapping("/result") //登录结果跳转
    public ModelAndView result(HttpServletRequest req, HttpServletResponse resp){
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        User user = new User();
        List<User> users = user.selectAll();
        boolean flag = false;
        for (User u : users) {
            if (u.getUsername().equals(username)&&u.getPassword().equals(password)){
                flag = true;
                user = u;
                break;
            }
        }

        ModelAndView modelAndView = new ModelAndView();
        if (flag){
            modelAndView.setViewName("redirect:/list");
            String token = UUID.randomUUID().toString();
            Cache.userCache.put(token, TranUtil.tranInfo(user,token));
            modelAndView.addObject("token", token);
        }else{
            modelAndView.setViewName("loginerror");
        }

        return modelAndView;
    }


    //查询全部
    @RequestMapping("/list")
    public ModelAndView userList(@RequestParam String token, @RequestParam(required = false) String keyword, Model model){
        ModelAndView modelAndView = new ModelAndView("index");
        UserVO user = Cache.userCache.get(token);
        List<Store> stores = new Store().selectAll();
        modelAndView.addObject("stores",stores);
        modelAndView.addObject("user",user);
        return modelAndView;
    }


    @RequestMapping("/query-store")
    public ModelAndView queryStore(@RequestParam String token){
        ModelAndView modelAndView = new ModelAndView("index");
        UserVO user = Cache.userCache.get(token);
        List<Store> stores = new Store().selectAll();
        modelAndView.addObject("stores",stores);
        modelAndView.addObject("user",user);
        return modelAndView;
    }

    @RequestMapping("/truncate-store")
    public ModelAndView truncateStore(@RequestParam String token){
        ModelAndView modelAndView = new ModelAndView("index");
        UserVO user = Cache.userCache.get(token);
        storeService.truncateStore();
        commodityService.truncateCommodity();
        List<Store> stores = new Store().selectAll();
        modelAndView.addObject("stores",stores);
        modelAndView.addObject("user",user);
        return modelAndView;
    }

    @RequestMapping("/create-store")
    public ModelAndView createStore(@RequestParam String token){
        ModelAndView modelAndView = new ModelAndView("index");

        Random random = new Random();
        int count = random.nextInt(15)+5;
        String type = "A";

        Set<String> set = new HashSet<>();
        Random r = new Random();
        while (set.size()<count){
            int d = r.nextInt(1000);
            set.add(type+String.valueOf(d));
        }

        for (String s : set) {
            Store store = new Store();
            store.setName(s);
            store.setType(type);
            String l = String.valueOf(r.nextInt(100));
            String t = String.valueOf(r.nextInt(100));
            store.setLongAndLat(l+","+t);
            store.setId(UUID.randomUUID().toString());
            store.insert();
        }


        LambdaQueryWrapper<Store> eq = Wrappers.<Store>query().lambda()
                .eq(Store::getType,type);
        List<Store> list = storeService.list(eq);
        list.forEach(s ->{
            // 商品个数
            int countc = random.nextInt(5)+1;
            for (int i = 0; i < countc; i++) {
                Commodity commodity = new Commodity();
                commodity.setId(String.valueOf(UUID.randomUUID()));
                String commodityName = CommodityConstants.map.get(i+1);
                commodity.setName(commodityName);
                commodity.setType(type);
                commodity.setStoreId(s.getId());
                // 商品数量（每个商品的数量）
                int total = random.nextInt(100);
                commodity.setTotal((double) total);
                commodity.insert();
            }
        });


        UserVO user = Cache.userCache.get(token);
        modelAndView.addObject("user",user);

        List<Store> stores = new Store().selectAll();
        modelAndView.addObject("stores",stores);


        return modelAndView;
    }

    @RequestMapping("/query-commoidty")
    public ModelAndView queryCommoidty(@RequestParam String token,@RequestParam String id){
        ModelAndView modelAndView = new ModelAndView("commodity");

        UserVO user = Cache.userCache.get(token);
        modelAndView.addObject("user",user);
        List<Commodity> commoditys = commodityService.getCommodityByStore(id);
        modelAndView.addObject("commoditys",commoditys);
        return modelAndView;
    }


    @RequestMapping("/tabu")
    public ModelAndView tabu(@RequestParam String token){
        ModelAndView modelAndView = new ModelAndView("tabu");

        UserVO user = Cache.userCache.get(token);
        modelAndView.addObject("user",user);

        List<Store> pathList = storeService.list();
        if (pathList.size()<=2){
            StringJoiner sj = new StringJoiner("->");
            for (Store store : pathList) {
                sj.add(store.getName());
            }
            String s = sj.toString();
            modelAndView.addObject("s",s);
            return modelAndView;
        }

        double[][] data = new double[pathList.size()][pathList.size()];
        // 根据坐标生成每个点之间的距离长度
        for (int i = 0; i < pathList.size(); i++) {
            String longAndLatFirst = pathList.get(i).getLongAndLat();
            String[] splitf = longAndLatFirst.split(",");
            int lf = Integer.parseInt(splitf[0]);
            int tf = Integer.parseInt(splitf[1]);

            for (int j = 0; j < pathList.size(); j++) {
                String longAndLatSecond = pathList.get(j).getLongAndLat();
                String[] splits = longAndLatSecond.split(",");
                int ls = Integer.parseInt(splits[0]);
                int ts = Integer.parseInt(splits[1]);

                int h = (ls - lf)>0? ls-lf:((ls-lf)*-1);
                int w = (ts - tf)>0? ts-tf:((ts-tf)*-1);
                int c = h*h+w*w;
                int sqrt = (int)Math.sqrt(c);
                data[i][j] = sqrt;
            }
        }


        int tabuLength = pathList.size() / 4;
        int optNum = pathList.size() / 2;

        int[] ints = TabuUtils.optTspByTabu(data, tabuLength, optNum);
        StringJoiner sj = new StringJoiner("->");
        for (int anInt : ints) {
            String storeName = pathList.get(anInt).getName();
            sj.add(storeName);
        }
        String s = sj.toString();
        modelAndView.addObject("s",s);

        List<String> orderList = new ArrayList<>();
        for (int anInt : ints) {
            Store store = pathList.get(anInt);
            orderList.add(store.getLongAndLat());
        }
        modelAndView.addObject("path",orderList);

        List<String> list = new ArrayList<>();
        list.add("[76,62]");
        list.add("[69,64]");
        list.add("[58,51]");
        list.add("[83,13]");
        list.add("[60,4],");
        list.add("[22,40]");
        list.add("[31,66]");
        list.add("[1,93],");
        list.add("[15,90]");
        list.add("[55,78]");
        list.add("[67,90]");
        list.add("[77,66]");
        modelAndView.addObject(list);
        return modelAndView;
    }
}
